package com.xmall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xmall.bean.bo.CommentBO;
import com.xmall.bean.bo.OrderShipStatus;
import com.xmall.bean.table.*;
import com.xmall.bean.table.System;
import com.xmall.bean.vo.*;
import com.xmall.mapper.CommentMapper;
import com.xmall.mapper.OrderGoodsMapper;
import com.xmall.mapper.OrderMapper;
import com.xmall.mapper.UserMapper;
import com.xmall.service.OrderService;
import com.xmall.mapper.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    OrderGoodsMapper orderGoodsMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CommentMapper commentMapper;
    @Autowired
    GoodsProductMapper goodsProductMapper;
    @Autowired
    AddressMapper addressMapper;
    @Autowired
    CartMapper cartMapper;
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    RegionMapper regionMapper;
    @Autowired
    CouponUserMapper couponUserMapper;
    @Autowired
    SystemMapper systemMapper;

    @Override
    public ListDataVo<Order> showList(Integer page, Integer limit, String sort, String order, Integer userId, String orderSn, Short orderStatusArray) {
        OrderExample orderExample = new OrderExample();
        orderExample.setOrderByClause(sort + " " + order);
        OrderExample.Criteria criteria= orderExample.createCriteria();
        if(userId != null){
            criteria.andUserIdEqualTo(userId);
        }
        if(orderSn != null){
            criteria.andOrderSnEqualTo(orderSn);
        }
        if(orderStatusArray != null){
            criteria.andOrderStatusEqualTo(orderStatusArray);
        }
        criteria.andDeletedEqualTo(false);
        List<Order> orders = orderMapper.selectByExample(orderExample);
        ListDataVo<Order> listDataVo = new ListDataVo<Order>();
        listDataVo.setItems(orders);
        PageInfo<Order> orderPageInfo = new PageInfo<>(orders);
        long total = orderPageInfo.getTotal();
        listDataVo.setTotal((int) total);
        return listDataVo;
    }

    @Override
    public OrderDetailVO showDetail(Integer id) {
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(id);
        List<OrderGoods> orderGoodsList = new LinkedList<>();
        orderGoodsList.add(orderGoods);
        Order order = orderMapper.selectByPrimaryKey(id);
        Integer userId = order.getUserId();
        User user = userMapper.selectByPrimaryKey(userId);
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        orderDetailVO.setOrder(order);
        orderDetailVO.setOrderGoods(orderGoodsList);
        orderDetailVO.setUser(user);
        return orderDetailVO;
    }

    /**
     * 同时删除order，order_goods,commment
     */
    @Override
    public void delete(@RequestBody Map<String,Integer> params) {
        //更新order表的delete
        Integer orderId = params.get("orderId");
        Order order = new Order();
        order.setId(orderId);
        order.setDeleted(true);
        orderMapper.updateByPrimaryKeySelective(order);
        //更新order_goods的delete 一对多的关系
        orderGoodsMapper.deleteByOrderId(orderId);
        //更新comment 表中的delete；
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
        for (OrderGoods orderGood : orderGoods) {
            //订单商品评论，如果是-1，则超期不能评价；如果是0，则可以评价；如果其他值，则是comment表里面的评论ID。
            //大于0  则有评价，逻辑删除
            if (orderGood.getComment() > 0){
                Comment comment = new Comment();
                comment.setDeleted(true);
                comment.setId(orderGood.getComment());
                commentMapper.updateByPrimaryKeySelective(comment);
            }
        }
    }

    @Override
    public Map<String, Object> queryDetail(Integer orderId) {
        Map<String, Object> result = new HashMap<>();
        //查询当前订单对应的商品信息,放入result中
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
        result.put("orderGoods",orderGoods);
        //查询订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        //订单状态转换
        String statusText = statusConverter(order.getOrderStatus());
        //封装
        OrderInfoVo orderInfoVo = new OrderInfoVo(order.getConsignee(),
                order.getAddress(),
                order.getAddTime(),
                order.getOrderSn(),
                order.getActualPrice(),
                order.getMobile(),
                statusText,
                order.getGoodsPrice(),
                order.getCouponPrice(),
                order.getId(),
                order.getFreightPrice(),
                new HandleOption());
        //根据订单状态，获取对应的option
        orderInfoVo.setHandleOption(optionConverter(order.getOrderStatus()));
        result.put("orderInfo",orderInfoVo);
        return result;
    }

    @Override
    public WxIndexOrderStatusVo queryOrderStatusByUserId(Integer userId) {

        int unpaid = orderMapper.countByUserIdAndStatusId(userId, 101);
        int unship = orderMapper.countByUserIdAndStatusId(userId, 201);
        int unrecv = orderMapper.countByUserIdAndStatusId(userId, 301);
        int uncomment1 = orderMapper.countByUserIdAndStatusId(userId, 401);
        int uncomment2 = orderMapper.countByUserIdAndStatusId(userId, 402);
        WxIndexOrderStatusInfoVo order = new WxIndexOrderStatusInfoVo(unrecv, uncomment1 + uncomment2, unpaid, unship);
        return new WxIndexOrderStatusVo(order);

    }

    @Override
    public Map<String, Object> queryList(Map<String, String> params) {
        //params：showType=1&page=1&size=10   还需要用户的信息查询对应的订单
        PageHelper.startPage(Integer.parseInt(params.get("page")),Integer.parseInt(params.get("size")));
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        //获取userId
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        Integer userId = user.getId();

        criteria.andUserIdEqualTo(userId);
        criteria.andDeletedEqualTo(false);
        //按状态查询
        if (params.get("showType").equals("1")){
            criteria.andOrderStatusEqualTo((short)101);
        }else if (params.get("showType").equals("2")){
            criteria.andOrderStatusEqualTo((short)201);
        }else if (params.get("showType").equals("3")){
            criteria.andOrderStatusEqualTo((short)301);
        }else if (params.get("showType").equals("4")){
            criteria.andOrderStatusGreaterThan((short)400);
        }

        List<Order> orders = orderMapper.selectByExample(orderExample);
        List<OrderListVO> orderListVOS = new ArrayList<>();
        //orders不空，则遍历
        if (!orders.isEmpty()){
            for (Order order : orders) {
                OrderListVO orderListVO = new OrderListVO();
                orderListVO.setOrderStatusText(statusConverter(order.getOrderStatus()));
                //团购价格为0  则isGroupin 为 false，否则为 true
                orderListVO.setGroupin(order.getGrouponPrice().compareTo(new BigDecimal(0)) != 0);
                orderListVO.setOrderSn(order.getOrderSn());
                orderListVO.setActualPrice(order.getActualPrice());
                orderListVO.setId(order.getId());
                //通过订单id 获取 订单中的商品list
                List<OrderGoodsVO> orderGoodsVOList = orderGoodsMapper.selectByOrdersId(order.getId());
                orderListVO.setGoodsList(orderGoodsVOList);
                //根据订单的状态，确定不同的 option
                HandleOption handleOption = optionConverter(order.getOrderStatus());
                orderListVO.setHandleOption(handleOption);
                orderListVOS.add(orderListVO);
            }
        }

        PageInfo<Order> orderPageInfo = new PageInfo<>(orders);
        long total = orderPageInfo.getTotal();
        int pages = orderPageInfo.getPages();
        Map<String, Object> result = new HashMap<>();
        result.put("count",total);
        result.put("totalPages",pages);
        result.put("data",orderListVOS);
        return result;
    }

    @Override
    public OrderGoods queryGoods(Integer orderId, Integer goodsId) {
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        criteria.andGoodsIdEqualTo(goodsId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
        //通过order ID 和 goodsId 可以唯一确定 一个订单中某个商品的信息，所以直接返回list的第一条数据
        return orderGoods.get(0);
    }

    @Override
    public void addComment(CommentBO commentBO) {

        Comment comment = new Comment();
        comment.setStar(commentBO.getStar());
        comment.setPicUrls(commentBO.getPicUrls());
        comment.setHasPicture(commentBO.getHasPicture());
        comment.setContent(commentBO.getContent());
        comment.setAddTime(new Date());
        comment.setUpdateTime(new Date());
        //根据用户来确定userId
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        Integer userId = user.getId();
        comment.setUserId(userId);
        //评论类型，如果type=0，则是商品评论；如果是type=1，则是专题评论；如果type=3，则是订单商品评论。
        comment.setType((byte) 0);
        OrderGoods orderGoods = orderGoodsMapper.selectByPrimaryKey(commentBO.getOrderGoodsId());
        comment.setValueId(orderGoods.getGoodsId());
        //插入一条评论
        commentMapper.insertSelective(comment);
        //更新ordergoods 中的 comment 属性
        orderGoods.setComment(comment.getId());
        orderGoodsMapper.updateByPrimaryKeySelective(orderGoods);
        //根据订单id查询订单,并减少待评价商品的数量
        Order order = orderMapper.selectByPrimaryKey(orderGoods.getOrderId());
        order.setComments((short)(order.getComments() - 1));
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void cancelOrder(Integer orderId) {
        //更改状态码，更新时间，endtime
        Order order = new Order();
        order.setOrderStatus((short) 102);
        order.setId(orderId);
        order.setEndTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void confirmOrder(Integer orderId) {
        //更新状态码，确认时间，更新时间
        Order order = new Order();
        order.setOrderStatus((short) 401);
        order.setId(orderId);
        order.setConfirmTime(new Date());
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void refund(Integer orderId) {
        //更新状态码，更新时间，

        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus((short) 202);
        order.setUpdateTime(new Date());
        orderMapper.updateByPrimaryKeySelective(order);
        //获取订单中各商品的数量
        OrderGoodsExample orderGoodsExample = new OrderGoodsExample();
        OrderGoodsExample.Criteria criteria = orderGoodsExample.createCriteria();
        criteria.andOrderIdEqualTo(orderId);
        List<OrderGoods> orderGoods = orderGoodsMapper.selectByExample(orderGoodsExample);
        //遍历更新库存
        for (OrderGoods orderGood : orderGoods) {
            GoodsProductExample goodsProductExample = new GoodsProductExample();
            GoodsProductExample.Criteria criteria1 = goodsProductExample.createCriteria();
            //通过goodsId 和 价格 来确定商品
            criteria1.andGoodsIdEqualTo(orderGood.getGoodsId());
            criteria1.andPriceEqualTo(orderGood.getPrice());
//            criteria1.andSpecificationsEqualTo((orderGood.getSpecifications())[0]);

            List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(goodsProductExample);
            GoodsProduct product = goodsProducts.get(0);
            //获得库存
            Integer number = product.getNumber();
            //更新商品库存
            product.setNumber(number + orderGood.getNumber());
            goodsProductMapper.updateByExampleSelective(product,goodsProductExample);
        }

    }

    @Transactional
    @Override
    public Map<String, Integer> submit(Map<String, String> params) {
        //{cartId: 281, addressId: 23, couponId: 0, message: "", grouponRulesId: 7, grouponLinkId: 0}
        //获取userId
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        Integer userId = user.getId();
//        Integer userId = 3;
        //获取地址
        Address address = addressMapper.selectByPrimaryKey(Integer.parseInt(params.get("addressId")));
        //获取购物车中下单的商品信息
        CartExample cartExample = new CartExample();
        CartExample.Criteria criteria = cartExample.createCriteria();
        if (Integer.parseInt(params.get("cartId")) == 0){
            //购物车付款
            criteria.andUserIdEqualTo(userId);
            criteria.andCheckedEqualTo(true);
            criteria.andDeletedEqualTo(false);
        }else {
            //商品详情页面付款
            criteria.andIdEqualTo(Integer.parseInt(params.get("cartId")));
        }
        List<Cart> carts = cartMapper.selectByExample(cartExample);
        Order order = new Order();
        order.setUserId(userId);
        order.setOrderSn(getOrderSn());
        order.setOrderStatus((short)101);
        order.setConsignee(address.getName());
        order.setMobile(address.getMobile());
        //获得地址
        order.setAddress(getAddress(address));
        if (params.get("message") != null){
            order.setMessage(params.get("message"));
        }
        order.setComments((short)carts.size());
        order.setAddTime(new Date());
        order.setUpdateTime(new Date());
        order.setGoodsPrice(getGoodsPrice(carts));
        //查询运费满减门槛
        Integer min = Integer.parseInt(getExpressValueByName("cskaoyan_mall_express_freight_min"));
        //查询运费
        Integer value = Integer.parseInt(getExpressValueByName("cskaoyan_mall_express_freight_value"));
        //满min 减免运费 value
         order.setFreightPrice(order.getGoodsPrice().compareTo(new BigDecimal(min))>0 ? new BigDecimal(0) : new BigDecimal(value));
        //不为0 则使用了优惠卷
        int couponId = Integer.parseInt(params.get("couponId"));
        if(couponId > 0){
            //获得优惠券的折扣
            order.setCouponPrice(getCouponPrice(couponId));
        }else {
            order.setCouponPrice(new BigDecimal(0));
        }
        order.setIntegralPrice(new BigDecimal(0));
        order.setGrouponPrice(new BigDecimal(0));
        //订单费用， = goods_price + freight_price - coupon_price
        order.setOrderPrice(order.getGoodsPrice().add(order.getFreightPrice()).subtract(order.getCouponPrice()));
        //实付费用， = order_price - integral_price
        order.setActualPrice(order.getOrderPrice().subtract(order.getIntegralPrice()));
        //生成订单
        orderMapper.insertSelective(order);
        Integer orderId = order.getId();
        //生成订单中每个商品的信息
        for (Cart cart : carts) {
            //初始化参数
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsId(cart.getGoodsId());
            orderGoods.setGoodsName(cart.getGoodsName());
            orderGoods.setGoodsSn(cart.getGoodsSn());
            orderGoods.setProductId(cart.getProductId());
            orderGoods.setNumber(cart.getNumber());
            orderGoods.setPrice(cart.getPrice());
            orderGoods.setSpecifications(cart.getSpecifications());
            orderGoods.setPicUrl(cart.getPicUrl());
            orderGoods.setAddTime(new Date());
            orderGoods.setUpdateTime(new Date());
            //插入数据
            orderGoodsMapper.insertSelective(orderGoods);
            //逻辑删除购物车的商品
            cart.setDeleted(true);
            cartMapper.updateByPrimaryKeySelective(cart);
        }
        //如果使用的优惠券，则改变优惠券的状态
        if (couponId != 0){
            setCouponStatus(userId,couponId,orderId);
        }

        Map<String, Integer> result = new HashMap<>();
        result.put("orderId",orderId);
        return result;
    }

    private String getExpressValueByName(String name){
        SystemExample systemExample = new SystemExample();
        SystemExample.Criteria criteria = systemExample.createCriteria();
        criteria.andKeyNameEqualTo(name);
        List<System> systems = systemMapper.selectByExample(systemExample);
        return systems.get(0).getKeyValue();
    }

    @Override
    public void prepay(Integer id) {
        Order order = new Order();
        order.setId(id);
        order.setOrderStatus((short)201);
        orderMapper.updateByPrimaryKeySelective(order);
    }

    @Override
    public void shipGoodsByOrdesId(OrderShipStatus orderShipStatus) {
        Order order = new Order();
        order.setShipChannel(orderShipStatus.getShipChannel());
        order.setShipSn(orderShipStatus.getShipSn());
        order.setShipTime(new Date());
        Short status = 301;
        order.setOrderStatus(status);
        OrderExample orderExample = new OrderExample();
        OrderExample.Criteria criteria = orderExample.createCriteria();
        criteria.andIdEqualTo(orderShipStatus.getOrderId());
        orderMapper.updateByExampleSelective(order,orderExample);
    }

    private void setCouponStatus(Integer userId, int couponId, Integer orderId) {
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andCouponIdEqualTo(couponId);
        CouponUser couponUser = new CouponUser();
        //使用状态, 如果是0则未使用；如果是1则已使用；如果是2则已过期；如果是3则已经下架；
        couponUser.setStatus((short) 1);
        couponUser.setOrderId(orderId);
        couponUser.setUsedTime(new Date());
        couponUser.setUpdateTime(new Date());
        couponUser.setDeleted(true);
        couponUserMapper.updateByExampleSelective(couponUser,couponUserExample);
    }

    //根据优惠券id 获取优惠券 折扣价格
    private BigDecimal getCouponPrice(int couponId) {
        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
        return coupon.getDiscount();
    }

    private BigDecimal getGoodsPrice(List<Cart> carts) {
        BigDecimal total = new BigDecimal(0);
        for (Cart cart : carts) {
            BigDecimal price = cart.getPrice();
            BigDecimal multiply = price.multiply(new BigDecimal(cart.getNumber()));
            total = total.add(multiply);
        }
        return total;
    }

    private String getAddress(Address address) {
        Region province = regionMapper.selectByPrimaryKey(address.getProvinceId());
        Region city = regionMapper.selectByPrimaryKey(address.getCityId());
        Region area = regionMapper.selectByPrimaryKey(address.getAreaId());
        String s = province.getName() + " " +city.getName() + " " + area.getName() + " " + address.getAddress();
        return s;
    }

    /**
     * 根据当前时间生成订单号，若同一时间下单多个，易重复
     * @return
     */
    private String getOrderSn() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return dateFormat.format(new Date());
    }

    private HandleOption optionConverter(Short orderStatus) {
        HandleOption handleOption = new HandleOption();
        if (orderStatus == 101){
            handleOption.setCancel(true);
            handleOption.setPay(true);
        }else if (orderStatus == 102 || orderStatus == 103 || orderStatus == 203){
            handleOption.setDelete(true);
        }else if (orderStatus == 201){
            handleOption.setRefund(true);
        }else if (orderStatus == 301){
            handleOption.setConfirm(true);
        }else if (orderStatus == 401 || orderStatus == 402){
            handleOption.setComment(true);
            handleOption.setDelete(true);
            handleOption.setRebuy(true);
        }
        return handleOption;
    }

    private String statusConverter(Short orderStatus) {
        if (orderStatus == 101){
            return "未付款";
        }else if (orderStatus == 102){
            return "用户取消";
        }else if (orderStatus == 103){
            return "系统取消";
        }else if (orderStatus == 201){
            return "已付款";
        }else if (orderStatus == 202){
            return "订单取消，退款中";
        }else if (orderStatus == 203){
            return "已退款";
        }else if (orderStatus == 301){
            return "已发货";
        }else if (orderStatus == 401){
            return "用户收货";
        }else {
            return "系统收货";
        }
    }


}
